package com.lgl.scs.userIndex.controller;

import com.lgl.scs.base.controller.BaseController;
import com.lgl.scs.userIndex.service.AppUserService;
import com.lgl.scs.util.service.UtilService;
import com.lgl.scs.util.utils.ControllerUtil;
import com.lgl.scsapi.system.model.AppUser;
import com.lgl.scsapi.system.model.PageData;
import com.lgl.scsapi.util.utils.AppUtil;
import com.lgl.scsapi.util.utils.BillNumberTool;
import com.lgl.scsapi.util.utils.Constants;
import com.lgl.scsapi.util.utils.Tools;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping(value="/userIndex/user")
public class UserController extends BaseController {
    @Resource(name="appUserService")
	private AppUserService appUserService;
    @Resource
    private RedisTemplate redisTemplate;
	@Resource
    private StringRedisTemplate stringRedisTemplate;
	@Resource(name="utilService")
	private UtilService utilService;

	//发送用户注册验证码
	@RequestMapping(value="/sendRegisterCheckCode")
	public Object sendRegisterCheckCode(HttpServletRequest request){
		PageData pd = this.getPageData();
		try {
			String phone = pd.getString("phone");
			if (!Tools.checkMobileNumber(phone)) {
				pd.put("status", "6"); //号码格式不对
				return pd;
			}
			boolean isRegister = appUserService.isExistsPhone(phone);
			if(isRegister){
				pd.put("status", "2");//号码已注册
				return pd;
			}
			return AppUtil.checkAndSendCode(request,phone,pd,stringRedisTemplate);
		} catch (Exception e) {
            log.error(e.toString(),e);
			pd.put("status", "3");//获取验证码失败
		}
		return pd;
	}
	//已经登录的后台发送注册验证码
	@RequestMapping(value="/sendCodeByLogin")
	public Object sendCodeByLogin(HttpServletRequest request){
		PageData pd = new PageData(3);
		try {
			AppUser appUser = this.getSessionAppUser();
			if (appUser == null){
				pd.put("status", "3");//未登录
				return pd;
			}
			return AppUtil.checkAndSendCode(request,appUser.getPhone(),pd,stringRedisTemplate);
		} catch (Exception e) {
			log.error(e.toString(),e);
			pd.put("status", "0");//获取验证码失败
		}
		return pd;
	}
	//PC端前台未登录时修改密码时发送验证码
	@RequestMapping(value="/sendCodeByNoLogin")
	public Object sendCodeByNoLogin(HttpServletRequest request){
		PageData pd = this.getPageData();
		try {
			String phone = pd.getString("phone");
			if (!Tools.checkMobileNumber(phone)) {
				pd.put("status", "6"); //号码格式不对
				return pd;
			}
			boolean isExists = appUserService.isExistsPhone(phone);
			if (!isExists){
				pd.clear();
				pd.put("status", "3"); //手机号码未注册
				return pd;
			}
			return AppUtil.checkAndSendCode(request,phone,pd,stringRedisTemplate);
		} catch (Exception e) {
			log.error(e.toString(),e);
			pd.put("status", "0");//获取验证码失败
		}
		return pd;
	}
	//判断手机号是否已存在,true:存在，false:不存在
	@RequestMapping(value="/isExistsPhone")
	public boolean isExistsPhone(HttpServletRequest request){
		String phone = request.getParameter("phone");
		return appUserService.isExistsPhone(phone);
	}
	//登录
	@RequestMapping(value="/toLogin", produces="application/json;charset=UTF-8")
	public Object toLogin(){
		Map<String, String> map = new HashMap(4);
		PageData pd = this.getPageData();
		//如果isMobile=Y，表示从微信端传来的登录请求，则不验证滑块信息
		String dragMoveX = (String) pd.remove("dragMoveX"), isMobile = (String) pd.remove("isMobile");
		dragMoveX = dragMoveX == null ? "0" : dragMoveX;
    	Integer moveX = (Integer) getRequest().getSession().getAttribute("location_x");
    	//如果滑块移动不在4像素范围内，则说明验证失败
    	if (!"Y".equals(isMobile)) {
    		if (moveX == null || moveX < 1){
				map.put("status", "6");
				return map;
			}
    		if ((Integer.valueOf(dragMoveX) > moveX + 4) || (Integer.valueOf(dragMoveX) <= moveX - 4)) {
            	map.put("status", "2");
            	return map;
            }
		}
		return ControllerUtil.checkUserLoginResult(pd,appUserService,utilService);
	}

	//注册
	@RequestMapping("/IamRegister")
	public Object IamRegister() {
		PageData pd = this.getPageData();
		try {
			String sendMsg = (String) pd.remove("sendMsg"), phone = pd.getString("phone");
			String phoneKey = Constants.PHONE_CHECK_CODE_K_PRE + phone;
			//从redis中取验证码，并与传过来的比较
            String redisCheckCode = stringRedisTemplate.opsForValue().get(phoneKey);
			if (!StringUtils.hasText(sendMsg) || !sendMsg.equals(redisCheckCode)) {
				pd.clear();
				pd.put("state", "3");
				return pd;
			}
			//用完了立刻删除，不要等自动过期，防止redis缓存被无用的数据占用
			stringRedisTemplate.delete(phoneKey);
			AppUser	appUser = appUserService.findByMobile(pd);
			String password = pd.getString("password");
			if(appUser != null ) {
				pd.put("state", "2");
				pd.remove("password");
				return pd;
			}
			if(!StringUtils.isEmpty(phone)){
				password = new SimpleHash(Constants.ALGORITHM_NAME,password,Constants.SHIRO_SALT,Constants.HASH_ITERATIONS).toHex();
				String userId = BillNumberTool.getRegisterUserId(stringRedisTemplate,0);
				pd.put("PASSWORD", password);
				pd.put("USERNAME", phone);
				pd.put("PHONE", phone);
				pd.put("USERID", userId);
				appUserService.saveAppUser(pd);
				pd.clear();
				pd.put("state", "1");
			}else {
				pd.put("state", "4");
			}

		} catch (Exception e) {
            log.error(e.toString(),e);
			pd.put("state", "0");
		}
		pd.remove("password");
		return pd;
	}
	//退出
	@RequestMapping(value="/toLogout")
	public Object toLogout(){
		//shiro管理的session
		Subject currentUser = SecurityUtils.getSubject();
		Session session = currentUser.getSession();
		session.removeAttribute(Constants.SESSION_USER);
		//shiro销毁登录
		SecurityUtils.getSubject().logout();
		return "0";
	}

	//查询我自己的其它信息
	@RequestMapping("/seeMyOtherInfo")
	public Object seeMyOtherInfo() {
		PageData pd = new PageData(3);
		try {
			AppUser appUser = this.getSessionAppUser();
			if (appUser == null || !SecurityUtils.getSubject().isAuthenticated()) {
				pd.put("status", "-1");
				return pd;
			}
			pd.put("USERNAME", appUser.getUserName());
			pd = appUserService.getMyOtherInfoByName(pd);
		} catch (Exception e) {
            log.error(e.toString(),e);
            pd.clear();
			pd.put("status", "1");
			return pd;
		}
		Map<String, Object> otherInfoMap = new HashMap(4);
		otherInfoMap.put("uoi", pd);
		otherInfoMap.put("status", "0");
		return otherInfoMap;
	}
	//编辑个人基本信息
	@RequestMapping("/editUserInfo")
	public Object editUserInfo() {
		PageData pd = this.getPageData();
		AppUser appUser = this.getSessionAppUser();
		if (appUser == null){
			pd.clear();
			pd.put("status", "3");
			return pd;
		}
		try {
			String oldPwd = (String) pd.remove("oldPwd"), newPwd = (String) pd.remove("newPwd");
			//修改密码，登录后通过我的页面作的修改
			if (StringUtils.hasText(oldPwd) && StringUtils.hasText(newPwd)) {
				oldPwd = new SimpleHash(Constants.ALGORITHM_NAME,oldPwd,Constants.SHIRO_SALT,Constants.HASH_ITERATIONS).toHex();
				newPwd = new SimpleHash(Constants.ALGORITHM_NAME,newPwd,Constants.SHIRO_SALT,Constants.HASH_ITERATIONS).toHex();
				pd.clear();
				pd.put("oldPwd", oldPwd);
				pd.put("newPwd", newPwd);
			}
			pd.put("USERNAME", appUser.getUserName());
			int row = appUserService.editMyOtherInfo(pd);
			pd.clear();
			pd.put("status", row > 0 ? "0" : "2");
		} catch (Exception e) {
            log.error(e.toString(),e);
			pd.put("status", "1");
		}
		return pd;
	}
	//修改手机号码
	@RequestMapping("/modifyMyPhone")
	public Object modifyMyPhone(HttpServletRequest request) {
		try {
			AppUser appUser = this.getSessionAppUser();
			String userNewPhone = request.getParameter("newPhone"),
					checkCode = request.getParameter("checkCode");
			String modifyStatus = appUserService.modifyMyPhone(appUser,userNewPhone,checkCode);
			if ("0".equals(modifyStatus)) {
                redisTemplate.delete(Constants.PHONE_CHECK_CODE_K_PRE + appUser.getPhone());
				appUser.setPhone(userNewPhone).setUserName(userNewPhone);
				SecurityUtils.getSubject().getSession().setAttribute(Constants.SESSION_USER, appUser);
			}
			return modifyStatus;
		} catch (Exception e) {
			log.error(e.toString(),e);
		}
		return "1";
	}
	//获取登录用户手机
	@RequestMapping("/getLoginUserPhone")
	public Object getLoginUserPhone() {
		PageData userPhonePd = new PageData(3);
		AppUser appUser = this.getSessionAppUser();
		if (appUser == null) {
			userPhonePd.put("status",-1);
			return userPhonePd;
		}
		userPhonePd.put("myPhone", appUser.getPhone());
		userPhonePd.put("status", "0");
		return userPhonePd;
	}

	//未登录的验证码方式修改密码(目前就前端登录页面，“忘记密码”修改密码)
	@RequestMapping("/modifyPwdByCodeWithNoLogin")
	public Object modifyPwdByCodeWithNoLogin() {
		PageData pd = this.getPageData();
		try {
			String myPhone = pd.getString("myPhone"), newPwd = (String) pd.remove("newPwd"), checkCode = (String) pd.remove("checkCode");
			return appUserService.modifyPwdByCheckCode(myPhone,newPwd,checkCode);
		} catch (Exception e) {
			log.error(e.toString(),e);
			pd.put("status", "1");
		}
		return pd;
	}
}